iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
Modern Web

小白大戰基礎網頁開發系列 第 23

D23 - XMLHttpRequest 來請求資料了!

  • 分享至 

  • xImage
  •  

前幾天有學到應用 AJAX 裡的 GET 和 POST 來請求資料, 今天要介紹另一個大家常用的請求資料方式, 也是 JavaScript 最有歷史的API:XMLHttpRequest (XHR)
網路業面可以透過 XMLHttpReuqest 送出 HTTP 請求的情況下, 具有同步非同步兩種取得資料的方法, 卻不需要實行頁面重載(page reload)導致的使用者中斷問題。
使用 XMLHttpReuqest 可以在自己的網頁上讀取遠端 JSON 資料,也就是跨越瀏覽器撈資料
從命名方式來看, 包含了 XML 和 HTTP, 但 XMLHttpRequest 不限於接收 XML 類型的資料, 任何其他類型的資料也是行的通的。

HTTP 請求方法回顧

  • 在預設情況下, fetch 是發出 GET 請求
  • 但還有其他方法, 比如, GET (拿取/讀取資源)、POST (新增資源)、PUT (更新一筆資源的所有內容)、DELETE (刪除指定資源) 等

如何跨瀏覽器撈取資料

Step 1.

設定 XMLHttpRequest (XHR) 變數 -> 建立一個 XHR object 來撈取遠端的資料。

var xhr = new XMLHttpRequest(); 

另外 object 內也有像onload, readyState等常用的屬性可以做應用
XMLHttpRequest.readyState
readyState 屬性會 return 一個 value 來判斷目前撈取資料的 status, 也就是XMLHttpRequest 客戶端 object 目前的 status

Value Status Description
0 UNSENT XHR 以成功產生, 代表客戶端已成立, 但還未連結要讀取的資料
1 OPENED open( ) 已被呼叫, 但尚未傳資料
2 HEADERS_RECEIVED send( ) 已被呼叫
3 LOADING 收到 response 內容的資料在 loading 中
4 DONE You’re done! 已成功撈取資料, 完成下載

參考資料: XMLHttpRequest.readyState

var xhr = new XMLHttpRequest(); // xhr.readyState; value 顯示為 0

Step 2.

使用xhr.open開啟一個 URL 去發起一個 HTTP 請求

xhr.open('GET', "http://www.xhr_example.com/xhr_example.txt", true); // xhr.readyState; value 顯示為 1
  • fist parameter: 撈取資料(GET), 傳送資料(POST)
  • second parameter: 要讀取的 URL
  • third parameter: 同步 (sync) 或非同步 (async); false -> 同步 (sync); true -> 非同步 (async)

Step 3.

使用xhr.send來傳送資料

  1. 拿來讀取資料的話, 並不會 POST 資料到後端, 括號內需要放 null(空值), 如果 send() 已經被呼叫到, 那麼此時 readyState 的 value 是 2
  2. 如果接下來成功讀取資料, 此時 readyState 的 value 是 4, 同時從 server 返回的文本 XMLHttpRequest.responseText 會把讀到的資料放置進去
xhr.send(null); // xhr.readyState; value 顯示為 4

Problem:
最後有件事要提醒一下大家, 之前我們有談到 sync 和 async 的差別與應用, 考慮在使用者友善的環境下, 預設會使用非同步 (async)去執行 program, 不過下了 send 指令後, 會需要等待一段時間去 load 要撈取的資料。為了不造成頁面 blocking 的現象, code 還是會繼續往下執行即使還沒撈到資料而不是等待資料傳回後, 才讓 code 繼續執行...那麼我們該如何打印出讀取到的資料 (responseText) 呢?
Solution: 使用 onload event

// onload 會確定當資料都有回傳後,才開始執行以下的 function, 讓 onload 來取回傳的值
xhr.onload= function(){
  console.log(xhr.responseText);
  if(xhr.status == 200){
    let jsonResponse = JSON.parse(xhr.responseText); // 資料在傳輸時, 是以 string 的格式來傳送, 但 JSON 是 Array 的格式
    // 把 return 回來的資料渲染到網頁上
    document.querySelector('.class name').textContent = jsonResponse[array index].array properties;
  } else{
      console.log('error');
  }
}

整合

var xhr = new XMLHttpRequest(); // xhr.readyState; value 顯示為 0
xhr.open('GET', "http://www.xhr_example.com/xhr_example.txt", true); // xhr.readyState; value 顯示為 1
xhr.send(null); // xhr.readyState; value 顯示為 4

// onload 會確定當資料都有回傳後,才開始執行以下的 function, 讓 onload 來取回傳的值
xhr.onload= function(){
  console.log(xhr.responseText);
  if(xhr.status == 200){
    let jsonResponse = JSON.parse(xhr.responseText); // 資料在傳輸時, 是以 string 的格式來傳送, 但 JSON 是 Array 的格式
    // 把 return 回來的資料渲染到網頁上
    document.querySelector('.class name').textContent = jsonResponse[array index].array properties;
  } else{
      console.log('error');
  }
}

上一篇
D22 - 常常讓人搞混的 Synchronous Programming 和 Asynchronous Programming
下一篇
D24 - 表單驗證 (Form Validation) 怎麼用
系列文
小白大戰基礎網頁開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言